package com.hengpeng.common.configuration;

import java.util.HashMap;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

import com.hengpeng.common.cis.ComponentContextLoader;
import com.hengpeng.common.configuration.entity.AnteSysPara;
import com.hengpeng.common.exception.SystemException;
import com.hengpeng.common.persist.AbstractDao;
import com.hengpeng.common.persist.NestedSimplyDao;

/**
 * <pre>
 * 系统配置参数
 * 将系统参数设置信息放入一个HashMap对象,避免多次访问数据库或文件系统.
 * </pre>
 * @author linriqing
 * @version 1.0, 2008-1-15
 */
@Component
@Lazy
@Scope("singleton")
public class CachedSystemConfig implements ApplicationContextAware
{
	private static final String AnteSysParaDao_BeanName = "com.hengpeng.common.configuration.CachedSystemConfig.SystemConfigDaoImpl";

	@Repository(AnteSysParaDao_BeanName)
	@Lazy
	public static final class SystemConfigDaoImpl extends AbstractDao<AnteSysPara>
	{
	}

	/**
	 * <pre>
	 * 私有静态内部类, 只有当有引用时, 该类才会被装载
	 * </pre>
	 * @author linriqing
	 * @version 1.0, 2009-6-19
	 */
	public final static class LazyInstance
	{
		protected final static HashMap<String, AnteSysPara> hmSysPara = new HashMap<String, AnteSysPara>();

		public static final CachedSystemConfig zzz_foo = new CachedSystemConfig();
	}

	private final static Log logger = LogFactory.getLog(CachedSystemConfig.class);

	/**
	 * <pre>
	 * 线程安全/单例模式的获取实例方法
	 * 注意:对于Spring来说不是安全的单例, 因为Spring会使用反射调用私有的构造函数...
	 * </pre>
	 * @return 系统配置参数
	 */
	public static CachedSystemConfig getInstance()
	{
		return ComponentContextLoader.getBean(CachedSystemConfig.class);
	}

	private NestedSimplyDao<AnteSysPara> systemConfigDao;

	private CachedSystemConfig()
	{
	}

	/**
	 * <pre>
	 * 判断一个系统参数是否已设值
	 * </pre>
	 * @param key 参数名称
	 * @return 是否已设值
	 */
	public boolean containsConfig(String key)
	{
		return LazyInstance.hmSysPara.containsKey(key);
	}

	/**
	 * <pre>
	 * 获取一个系统配置参数对象
	 * </pre>
	 * @param key 参数名称
	 * @return 参数对象
	 */
	public AnteSysPara getConfig(String key)
	{
		if (LazyInstance.hmSysPara.containsKey(key))
		{
			return LazyInstance.hmSysPara.get(key);
		}
		else
		{
			AnteSysPara anteSysPara = systemConfigDao.get(key);
			if (anteSysPara != null)
			{
				LazyInstance.hmSysPara.put(anteSysPara.getParaKey(), anteSysPara);
				return anteSysPara;
			}
			else
			{
				throw new SystemException("不存在或未初始化系统参数{" + key + "}...");
			}
		}
	}

	/**
	 * <pre>
	 * 获取一个系统配置参数字符串
	 * </pre>
	 * @param key 参数名称
	 * @return 参数值
	 */
	public String getConfigValue(String key)
	{
		if (LazyInstance.hmSysPara.containsKey(key))
		{
			String value = (String) LazyInstance.hmSysPara.get(key).getParaValue();
			return value;
		}
		else
		{
			AnteSysPara anteSysPara = systemConfigDao.get(key);
			if (anteSysPara != null)
			{
				LazyInstance.hmSysPara.put(anteSysPara.getParaKey(), anteSysPara);
				return anteSysPara.getParaValue();
			}
			else
			{
				throw new SystemException("不存在或未初始化系统参数{" + key + "}...");
			}
		}
	}

	/**
	 * <pre>
	 * 获取一个系统配置参数字符串
	 * </pre>
	 * @param key 参数名称
	 * @param defaultValue 不存在时返回的默认值
	 * @return 参数值
	 */
	public String getConfigValue(String key, String defaultValue)
	{
		if (LazyInstance.hmSysPara.containsKey(key))
		{
			String value = (String) LazyInstance.hmSysPara.get(key).getParaValue();
			return value;
		}
		else
		{
			AnteSysPara anteSysPara = systemConfigDao.get(key);
			if (anteSysPara != null)
			{
				LazyInstance.hmSysPara.put(anteSysPara.getParaKey(), anteSysPara);
				return anteSysPara.getParaValue();
			}
			else
			{
				return defaultValue;
			}
		}
	}

	/**
	 * <pre>
	 * 移出一个系统配置参数
	 * </pre>
	 * @param key 参数名称
	 */
	public void removeConfig(String key)
	{
		if (LazyInstance.hmSysPara.containsKey(key))
		{
			LazyInstance.hmSysPara.remove(key);
			systemConfigDao.deleteById(key);
		}
	}

	/**
	 * <pre>
	 * 增加或重新设置一个系统配置参数
	 * </pre>
	 * @param value 配置参数
	 */
	public void setConfig(AnteSysPara value)
	{
		if (LazyInstance.hmSysPara.containsKey(value.getParaKey()))
		{
			AnteSysPara persist = systemConfigDao.load(value.getParaKey());
			persist.setParaValue(value.getParaValue());
			persist.setParaDesc(value.getParaDesc());
			systemConfigDao.update(persist);
		}
		else
		{
			systemConfigDao.save(value);
		}
		LazyInstance.hmSysPara.put(value.getParaKey(), value);
	}

	@SuppressWarnings("unchecked")
	@Override
	public void setApplicationContext(ApplicationContext arg0) throws BeansException
	{
		this.systemConfigDao = (NestedSimplyDao<AnteSysPara>) arg0.getBean(AnteSysParaDao_BeanName);
		List<AnteSysPara> list = systemConfigDao.findAll();
		if ((list != null) && (list.size() > 0))
		{
			for (int i = 0; i < list.size(); i++)
			{
				AnteSysPara anteSysPara = (AnteSysPara) list.get(i);
				LazyInstance.hmSysPara.put(anteSysPara.getParaKey(), anteSysPara);
				if (logger.isDebugEnabled())
				{
					logger.debug("加载系统参数{" + anteSysPara.getParaKey() + "->" + anteSysPara.getParaValue() + "}...");
				}
			}
			logger.info("共加载系统参数{" + list.size() + "}个...");
		}
	}
}
